import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import IA.Energia.Centrales;
import IA.Energia.Cliente;
import IA.Energia.Clientes;
import aima.search.framework.Problem;
import aima.search.framework.Search;
import aima.search.framework.SearchAgent;
import aima.search.informed.HillClimbingSearch;


public class Experimento1 implements IExperiment {
	List<List<String>> result = new ArrayList<List<String>>();
	double prTipos[];
	double prContratos;
	int tiposCentrales[];
	int nclientes;
	int numreplicas;
	boolean operador[];
	int solucionInicial;
	String nombre;
	double penalizacion = 0.0f;
	
	public Experimento1(String nombre, boolean[] operadores, int numreplicas, int solucionInicial, int numClientes, int[] tiposcentrales, double pgarantizados, double[] ptipoclientes, double penalizacion) {
		prTipos = ptipoclientes;
		prContratos = pgarantizados;
		tiposCentrales = tiposcentrales;
		nclientes = numClientes;
		this.numreplicas = numreplicas;
		this.solucionInicial = solucionInicial;
		operador = operadores;
		this.nombre = nombre;
		this.penalizacion = penalizacion;
	}
	@Override
	public void init() {
		result = new ArrayList<List<String>>();
	}

	@Override
	public void execute() {
		/**
		 * Experimento 1
		 */
		
		
		Clientes clientes = null;
		/*boolean[][] operador = {
				{false, true, true, false},
				{false, false, false, true},
				{false, false, true, false},
				{false, true, false, false},
				{true, false, false, false},
				{false, false, true, true},
				{false, true, false, true},
				{true, true, false, false},
				{true, false, true, false},
				{true, true, true, false},
				{true, true, true, false},
				{true, true, false, true},
				{true, false, true, true},
				{false, true, true, true},
				{true, true, true, true}
		};*/
		List<String> cols = new ArrayList<String>();
		cols.add("Nombre experimento;");
		cols.add("Algoritmo;");
		cols.add("Put;");
		cols.add("Delete;");
		cols.add("Move;");
		cols.add("Swap;");
		cols.add("Replica;");
		cols.add("Tipo Sol. Ini.;");
		cols.add("N clientes;");
		cols.add("Centrales Tipo A;");
		cols.add("Centrales Tipo B;");
		cols.add("Centrales Tipo C;");
		cols.add("% Garantizados;");
		cols.add("% tipo clientes G;");
		cols.add("% tipo clientes MG;");
		cols.add("% tipo clientes XG;");
		cols.add("Tiempo ms");
		cols.add("Beneficio");
		cols.add("Nodos expandidos");
		result.add(cols);
		for (int j = 0; j < numreplicas; j++) {
			cols.add(nombre);
			cols.add("Hillclimbing");
			cols.add(String.valueOf(operador[2]));
			cols.add(String.valueOf(operador[1]));
			cols.add(String.valueOf(operador[0]));
			cols.add(String.valueOf(operador[3]));
			cols.add(String.valueOf(j+1));
			cols.add(solucionInicial == 0 ? "linear" : solucionInicial == 1 ? "random" : "greedy");
			cols.add(String.valueOf(nclientes));
			cols.add(String.valueOf(tiposCentrales[0]));
			cols.add(String.valueOf(tiposCentrales[1]));
			cols.add(String.valueOf(tiposCentrales[2]));
			cols.add(String.valueOf(prContratos));
			cols.add(String.valueOf(prTipos[0]));
			cols.add(String.valueOf(prTipos[1]));
			cols.add(String.valueOf(prTipos[2]));
			
			long tstart = System.currentTimeMillis();
			int semilla = (int) Math.random() * 1000;
				Map<String, String> valuesT = new HashMap<String, String>();
				Map<String, String> valuesB = new HashMap<String, String>();
				Map<String, String> valuesS = new HashMap<String, String>();
				boolean cambiar = operador[0], 
						quitar = operador[1], 
						anadir = operador[2],
						intercambiar = operador[3];
				try {
					clientes = new Clientes(nclientes, prTipos , prContratos, semilla);
					
				} catch (Exception e1) {
					System.out.println("ERROR AL GENERAR CLIENTES: " + e1.getMessage());
					System.exit(1);
				}
				
				Centrales centrales = null;
				
				try {
					centrales = new Centrales(tiposCentrales, semilla);
				} catch (Exception e1) {
					System.out.println("ERROR AL GENERAR CENTRALES: " + e1.getMessage());
					System.exit(1);
				}
				Estado estadoInicial = new Estado(clientes, centrales, 1);
				estadoInicial.setIncPenalizacion(penalizacion);
				Problem problem = new Problem(estadoInicial
												, new EnergiaSuccessor( cambiar, quitar, anadir, intercambiar)
												, new EnergiaGoalTest()
												, new EnergiaHeuristica());
				
				Search search = new HillClimbingSearch();
				try {
					SearchAgent searchAgent = new SearchAgent(problem, search);
					long tfinish = System.currentTimeMillis();
					cols.add(String.valueOf(tfinish-tstart));
					cols.add("-");
					cols.add(String.valueOf(searchAgent.getActions().size()));
					
				} catch (Exception e) {
					System.out.println("ERROR: " + e.getMessage());
				}
				result.add(cols);
		}

	}

	@Override
	public List<List<String>> getResult() {
		// TODO Auto-generated method stub
		return result;
	}

}
